package com.cuhk.gulimall.product.utils;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

public class VoToPo {

    private static String packageNameEntity = "com.cuhk.gulimall.product.entity.";
    private static String packageNameVO = "com.cuhk.gulimall.product.vo.";
    private static String suffixEntity = "Entity";
    private static String suffixVO = "VO";

    public static <T, E> boolean transfer(T t, E e, int type) throws IllegalAccessException {
        Class clazzT = t.getClass();
        Class clazzE = e.getClass();
        String nameSrc = type == 0 ? clazzT.getName().substring(packageNameEntity.length()) :
                clazzE.getName().substring(packageNameVO.length());

        String nameTarget = type == 0 ? clazzE.getName().substring(packageNameVO.length()) :
                clazzT.getName().substring(packageNameEntity.length());

        String suffixSrc = type == 0 ? suffixEntity : suffixVO;
        String suffixTarget = type == 0 ? suffixVO : suffixEntity;

        String prefixSrc = nameSrc.substring(0, nameSrc.length() - suffixSrc.length());
        String prefixTarget = nameTarget.substring(0, nameTarget.length() - suffixTarget.length());


        // PO 和 EO对应的类型不匹配
        // 无法转型
        if(!prefixSrc.equals(prefixTarget)) {
            return false;
        }
        else {
            Map<String, Object> map = new HashMap<>();
            Field[] fields = type == 0 ? clazzT.getDeclaredFields() : clazzE.getDeclaredFields();
            Object m = type == 0 ? t : e;
            for(Field field : fields) {
                field.setAccessible(true);
                String name = field.getName();
                Object value = field.get(m);
                if(value != null) {
                    map.put(name, value);
                }
            }
            Field[] fieldsVo = type == 0 ? clazzE.getDeclaredFields() : clazzT.getDeclaredFields();
            Object v = type == 0 ? e : t;
            for(Field field : fieldsVo) {
                field.setAccessible(true);
                if(map.containsKey(field.getName())) {
                    field.set(v, map.get(field.getName()));
                }
            }
            return true;
        }
    }
}
